Save Jupyter Notebook as HTML¶

1. Import Modules¶

In [1]:
import math
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

Set export settings to include plotly figures in HTML

In [2]:
import plotly.io as pio
pio.renderers.default = "notebook"

2. Example Data and Visualization¶

2.1 Import World Happiness Report as example data¶

In [3]:
whr = pd.read_csv("./test_data_public/WHR_data.csv")
In [4]:
whr.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1367 entries, 0 to 1366
Data columns (total 11 columns):
 #   Column                        Non-Null Count  Dtype  
---  ------                        --------------  -----  
 0   Year                          1367 non-null   int64  
 1   country                       1367 non-null   object 
 2   region                        1367 non-null   object 
 3   Ranking                       1367 non-null   float64
 4   happiness_score               1367 non-null   float64
 5   gdp_per_capita                1367 non-null   float64
 6   social_support                1367 non-null   float64
 7   healthy_life_expectancy       1366 non-null   float64
 8   freedom_to_make_life_choices  1367 non-null   float64
 9   generosity                    1367 non-null   float64
 10  perceptions_of_corruption     1366 non-null   float64
dtypes: float64(8), int64(1), object(2)
memory usage: 117.6+ KB
In [5]:
whr.describe()
Out[5]:
Year Ranking happiness_score gdp_per_capita social_support healthy_life_expectancy freedom_to_make_life_choices generosity perceptions_of_corruption
count 1367.000000 1367.000000 1367.000000 1367.000000 1367.000000 1366.000000 1367.000000 1367.000000 1366.000000
mean 2018.903438 76.580834 5.441086 1.019422 1.045334 0.584043 0.450771 0.196260 0.132275
std 2.561006 44.088743 1.117909 0.453703 0.331163 0.245117 0.156733 0.113301 0.112555
min 2015.000000 1.000000 1.859000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
25% 2017.000000 38.500000 4.599500 0.696326 0.832022 0.402301 0.356000 0.115000 0.056826
50% 2019.000000 76.500000 5.440000 1.043000 1.083000 0.612830 0.467610 0.182700 0.097000
75% 2021.000000 114.000000 6.256300 1.338473 1.299985 0.777614 0.568685 0.252858 0.165945
max 2023.000000 158.000000 7.842000 2.209000 1.644000 1.141000 0.772000 0.838075 0.587000

2.2 Create example figure with subplots¶

In [6]:
def get_color_sequenze(color_sequenze):
    if color_sequenze == "default":
        # Get active plotly-theme
        active_plotly_theme = pio.templates.default
        # Get default line colors for theme
        color_sequenze = pio.templates[active_plotly_theme].layout['colorway']
    elif color_sequenze == "Plotly":
        color_sequenze = px.colors.qualitative.Plotly
    elif color_sequenze == "D3":
        color_sequenze = px.colors.qualitative.D3
    elif color_sequenze == "T10":
        color_sequenze = px.colors.qualitative.T10
    elif color_sequenze == "Alphabet":
        color_sequenze = px.colors.qualitative.Alphabet
    elif color_sequenze == "Dark24":
        color_sequenze = px.colors.qualitative.Dark24
    elif color_sequenze == "Light24":
        color_sequenze = px.colors.qualitative.Light24
    elif color_sequenze == "Set1":
        color_sequenze = px.colors.qualitative.Set1
    elif color_sequenze == "Pastel1":
        color_sequenze = px.colors.qualitative.Pastel1
    elif color_sequenze == "Dark2":
        color_sequenze = px.colors.qualitative.Dark2
    elif color_sequenze == "Pastel2":
        color_sequenze = px.colors.qualitative.Pastel2
    elif color_sequenze == "Set3":
        color_sequenze = px.colors.qualitative.Set3
    elif color_sequenze == "Antique":
        color_sequenze = px.colors.qualitative.Antique
    elif color_sequenze == "Bold":
        color_sequenze = px.colors.qualitative.Bold
    elif color_sequenze == "Pastel":
        color_sequenze = px.colors.qualitative.Pastel
    elif color_sequenze == "Prism":
        color_sequenze = px.colors.qualitative.Prism
    elif color_sequenze == "Safe":
        color_sequenze = px.colors.qualitative.Safe
    elif color_sequenze == "Vivid":
        color_sequenze = px.colors.qualitative.Vivid

    return color_sequenze
In [7]:
def create_subplots(
  df,
  x,
  y,
  rows,
  cols,
  hue,
  title,
  color_sequenze_name = "default",
  fig_height = None,
  fig_width = None   
):
    
    legends = df[hue].unique()

    color_sequenze = get_color_sequenze(color_sequenze=color_sequenze_name)

    if len(color_sequenze) < len(legends):
        color_sequenze = color_sequenze * math.ceil(len(legends)/len(color_sequenze))

    colors = dict(zip(legends, color_sequenze))

    fig = make_subplots(rows=rows, cols=cols, subplot_titles=y)

    for legend in legends:

        row = 1
        col = 1

        temp_df = df[df[hue] == legend]

        for x_item, y_item in zip(x, y):

            if (row == 1) & (col == 1):

                fig.add_trace(
                    go.Scatter(
                        x=temp_df[x_item],
                        y=temp_df[y_item],
                        name=legend,
                        legendgroup = legend,
                        line=dict(color=colors[legend]),
                        showlegend=True
                    ), row=row, col=col
                )

                col += 1

                if col > cols:
                    col = 1
                    row += 1


            else:
                fig.add_trace(
                    go.Scatter(
                        x=temp_df[x_item],
                        y=temp_df[y_item],
                        name=legend,
                        legendgroup = legend,
                        line=dict(color=colors[legend]),
                        showlegend=False
                    ), row=row, col=col
                )

                col += 1

                if col > cols:
                    col = 1
                    row += 1

    fig.update_layout(title_text=title)

    if not (fig_height == None) & (fig_height == None):
        fig.update_layout(height=fig_height, width=fig_width)

    return fig
In [8]:
create_subplots(
    df = whr[whr['country'].isin(['Germany', 'Austria', 'Switzerland', 'Italy', 'Iceland', 'France', 'Norway', 'Sweden', 'Denmark', 'Belgium', 'Netherlands'])],
    x=['Year', 'Year', 'Year', 'Year', 'Year', 'Year'],
    y=['Ranking', 'happiness_score', 'gdp_per_capita', 'social_support', 'healthy_life_expectancy', 'freedom_to_make_life_choices'],
    rows=2,
    cols=3,
    hue='country',
    title='World Happiness Report',
    color_sequenze_name="Plotly",
    fig_height=600,
    fig_width=1400
).show()

3. Save as HTML¶

Note:

Plotly settings have to be set to inculde plotly figures to HTML.
import plotly.io as pio
pio.renderers.default = "notebook"

If jupyter nbconvert ist not installed yet, install it to your venv with pip install nbconvert

Official nbconvert Documentation

In [ ]:
!jupyter nbconvert --to html "save_jupyter_notebook_as_html.ipynb"

If only the output and markdown should be shown in the HTML-file, --no-input needs to be added at the end of the line.
For example:

!jupyter nbconvert --to html "2024-06-04_Auswertung.ipynb" --no-input